Fleet UI: Unreleased bug fixes to command palette (AB vs ABM, Controls on Fleet Free, emoji not italicized)#47432
Conversation
The settings page already uses "Apple Business (AB)" / "Add AB" / "Edit AB", but the command palette still showed "Apple Business Manager (ABM)". Aligns the palette labels with the settings UI. Internal IDs (add-abm, edit-abm, isAbmConfigured) and "abm" search keywords are kept — same convention as team_id staying after the teams→fleets rename, and preserves muscle-memory search for users who type "abm". Resolves #47384.
On Fleet Free, currentTeam stays undefined (no team picker exists), so hasTeamOrUnassigned evaluated to false, gating out the entire Controls group, the Controls page link in Pages, and Add script in Commands — even though Configuration profiles, Scripts, and Variables all work on Free. The Free test fixture was masking this by faking hasTeamSelected: true; corrected to mirror production state. Treat Free as team-or-unassigned in the derivation so team-gated palette items still surface on Free-available destinations. Premium-only items (OS updates, Disk encryption, Setup experience, Certificates, Passwords) remain hidden via their own isPremiumTier gates.
Fleet names with emoji prefixes (e.g. "💻 Workstations") rendered with a slanted emoji inside the italic right-side chip — browsers fake italic by shearing every glyph, including emoji. Adds an UprightEmoji component that splits the string on emoji graphemes (Extended_Pictographic + VS-16 + ZWJ sequences, plus regional indicator pairs for flags) and wraps each emoji run in a span with font-style: normal. Applied to the host picker team column and the main palette's teamName chip. Italic + grey treatment is preserved on the Latin text, matching the existing secondary-text convention. Uses String.replace with a callback instead of String.matchAll so the helper compiles against the project's ES2019 / ES2021.String lib target (matchAll is in ES2020.String, which isn't loaded).
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #47432 +/- ##
========================================
Coverage 67.22% 67.22%
========================================
Files 3305 3351 +46
Lines 228031 228169 +138
Branches 11751 11915 +164
========================================
+ Hits 153286 153379 +93
- Misses 60930 60974 +44
- Partials 13815 13816 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
On Free, four palette items routed to destinations that immediately render <PremiumFeatureMessage />: Controls (redirects to OS updates), OS updates, SSO for end users (paywalled tab), and Identity provider. The palette is for actions, not for marketing the paid tier — gate each entry on isPremiumTier so it's hidden on Free. Free users still reach the tier-free Controls sub-pages (OS settings, Scripts, Variables) via their own palette entries. Codify the rule in .claude/skills/command-palette/SKILL.md so future palette entries get the same check.
There was a problem hiding this comment.
Pull request overview
This PR delivers a set of frontend-only command palette (⌘K) fixes to align terminology, correct tier/team gating on Fleet Free, and improve rendering of fleet names that include emoji in italicized UI surfaces.
Changes:
- Update command palette labels from “Apple Business Manager (ABM)” to “Apple Business (AB)” while preserving existing internal IDs/keywords.
- Fix Fleet Free command palette gating so Free-available Controls destinations (OS settings, Scripts, Variables, etc.) surface even when
currentTeamis unset. - Add an
UprightEmojirenderer to prevent italic styling from shearing emoji glyphs in fleet/team name chips and the host picker team column.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/components/CommandPalette/helpers.tests.ts | Updates Fleet Free fixture to match production and adds regression tests for Free-available vs Premium-walled entries; adjusts AB label test names. |
| frontend/components/CommandPalette/groups/settings.ts | Gates Premium-walled Integrations sub-items (SSO end users, Identity provider) behind isPremiumTier. |
| frontend/components/CommandPalette/groups/pages.ts | Hides the /controls page entry on Free (since it redirects to Premium OS updates) while keeping other Controls entries available. |
| frontend/components/CommandPalette/groups/mdm.ts | Renames ABM → AB in the command palette display label while retaining internal IDs. |
| frontend/components/CommandPalette/groups/derivations.ts | Treats Fleet Free as “team-or-unassigned” to avoid incorrectly hiding team-gated items when no team picker exists. |
| frontend/components/CommandPalette/groups/controls.ts | Gates OS updates entry behind isPremiumTier; preserves Free-available Controls sub-pages. |
| frontend/components/CommandPalette/components/UprightEmoji.tsx | Adds emoji-aware rendering to keep emoji upright inside italicized parent elements. |
| frontend/components/CommandPalette/components/UprightEmoji.tests.tsx | Adds unit tests for emoji segmentation and rendering behavior. |
| frontend/components/CommandPalette/components/HostPicker.tsx | Uses UprightEmoji for the host picker team column. |
| frontend/components/CommandPalette/CommandPalette.tsx | Uses UprightEmoji for team/fleet “chip” labels in results. |
| .claude/skills/command-palette/SKILL.md | Updates internal authoring guidance to gate palette items that land on Premium paywalls. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
WalkthroughThis PR adds UprightEmoji (with splitEmojiSegments) and tests, replaces plain team-name text with UprightEmoji in CommandPalette and HostPicker, adds isPremiumTier to derived palette context and treats Free as team-or-unassigned, gates OS updates, Controls page, SSO, and IdP entries to Premium users, updates Apple Business labeling from ABM to AB, and updates tests to reflect Free/premium visibility changes. Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@frontend/components/CommandPalette/components/UprightEmoji.tests.tsx`:
- Around line 39-53: Add tests in UprightEmoji.tests.tsx to cover emoji
sequences with Emoji_Modifier (skin tones) so splitEmojiSegments treats them as
single grapheme segments; specifically add assertions for simple modifier pairs
like "👍🏽" and for modifier + ZWJ sequences like "👨🏽💻" ensuring each yields
one { text: "<emoji>", isEmoji: true } segment followed by the remaining text as
non-emoji, and place them alongside the existing ZWJ and regional indicator
tests to prevent regressing parsing of \p{Emoji_Modifier} sequences.
In `@frontend/components/CommandPalette/components/UprightEmoji.tsx`:
- Line 12: EMOJI_RUN_RE in UprightEmoji.tsx currently omits \p{Emoji_Modifier},
so skin-tone modifiers (e.g., 👍🏽 or 👨🏽💻) can be split; update the
EMOJI_RUN_RE pattern to include \p{Emoji_Modifier} inside the pictographic
sequence (alongside \p{Extended_Pictographic}) so modifier codepoints are
treated as part of the same grapheme run and not split across nodes; locate the
EMOJI_RUN_RE constant and extend its character classes/groups to allow
\p{Emoji_Modifier} in the same positions as Extended_Pictographic (and keep the
existing ZWJ/Regional_Indicator handling intact).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: ee143502-d39e-4aa5-8817-8d88858c50d0
⛔ Files ignored due to path filters (1)
.claude/skills/command-palette/SKILL.mdis excluded by!**/*.md
📒 Files selected for processing (10)
frontend/components/CommandPalette/CommandPalette.tsxfrontend/components/CommandPalette/components/HostPicker.tsxfrontend/components/CommandPalette/components/UprightEmoji.tests.tsxfrontend/components/CommandPalette/components/UprightEmoji.tsxfrontend/components/CommandPalette/groups/controls.tsfrontend/components/CommandPalette/groups/derivations.tsfrontend/components/CommandPalette/groups/mdm.tsfrontend/components/CommandPalette/groups/pages.tsfrontend/components/CommandPalette/groups/settings.tsfrontend/components/CommandPalette/helpers.tests.ts
EMOJI_RUN_RE already accepts \p{Emoji_Modifier} after each Extended_Pictographic
codepoint in a ZWJ sequence, but the existing tests only cover the two cases
separately (👨💻 for ZWJ alone, 👍🏽 for a modifier alone). Add a 👨🏽💻 case so
the combined-grapheme behavior is pinned.
Issue
Closes #47384
Closes #47383
Closes #47417
Description
Three command palette (⌘K) bug fixes, each in its own commit so reviewers can read them independently:
The settings page already says "Apple Business (AB)" / "Add AB" / "Edit AB", but the palette still showed the old "Apple Business Manager (ABM)" labels. Renamed the displayed labels to match. Internal IDs (add-abm, edit-abm, isAbmConfigured) and "abm" search keywords are kept — same convention as team_id staying after the teams→fleets rename, and preserves muscle-memory search.
On Fleet Free, the entire Controls group was hidden from the palette — Configuration profiles, Scripts, Script library, Script batch progress, Variables, the Controls page link, and Add script were all unreachable. Root cause: currentTeam stays undefined on Free (no team picker exists), so hasTeamOrUnassigned evaluated false and gated out everything. Fix: treat Free as team-or-unassigned in the derivation, since the team concept doesn't apply on Free. Premium-only Controls items (OS updates, Disk encryption, Setup experience, Certificates, Passwords) stay hidden in the command palette to not bait-and-switch users onto a page that they don't have access to. Also corrected the FREE_CONTEXT test fixture, which was masking the bug by faking hasTeamSelected: true, and added positive tests for the Free-available items.
#45210
Fleet names with emoji prefixes (e.g. "💻 Workstations", "📱🔐 Personal mobile devices") rendered with a tilted/slanted emoji inside the italic right-side chip and the host picker's team column. Cause: browsers fake italic by shearing every glyph, including emoji. Added an UprightEmoji component that splits the string on emoji graphemes
(Extended_Pictographic + VS-16 + ZWJ sequences, plus regional indicator pairs for flag emoji) and wraps each emoji run in a span with font-style: normal. Italic + grey treatment is preserved on the Latin text — that styling matches Fleet's existing secondary-text convention.
Testing
Summary by CodeRabbit
New Features
Bug Fixes / Behavior Changes
Updates